<?php

namespace App\Library\Logic;

use App\Library\Requests\Base\BasePageRequest;
use App\Library\Requests\ProductOrderReturn\ProductOrderReturnPageRequest;
use App\Library\Requests\ProductOrderReturn\ProductOrderReturnSellerPageRequest;
use App\Library\Requests\ProductOrderReturn\ProductOrderReturnUserPageRequest;
use App\Models\ShopOrderReturnModel;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class ShopOrderReturnLogic extends ShopOrderReturnModel
{
    /**
     * paging
     * @param ProductOrderReturnPageRequest $request
     * @return array
     */
    public function paging(ProductOrderReturnPageRequest $request): array
    {
        $builder = self::query()->leftJoin('shop_order', 'shop_order.order_id', 'shop_order_return.order_id')
            ->leftJoin('shop_order_ext', 'shop_order_ext.order_id', 'shop_order.order_id')
            ->leftJoin('shop_order_goods', 'shop_order_goods.order_id', 'shop_order.order_id')
            ->leftJoin('shop_user', 'shop_user.user_id', 'shop_order_ext.user_id');
        if (!is_null($request->expressNo)) {
            $builder->leftJoin('logistics', function ($join) {
                $join->on('logistics.object_id', 'shop_order.order_id')->where('logistics.type', 1)
                    ->where('logistics.object_type', 1);
            })->where('logistics.express_no', $request->expressNo);
            $request->offsetUnset('expressNo');
        }
        return paginate(helpBuilder($builder->with('goods')->groupBy('shop_order_return.or_id')
            ->orderByDesc('shop_order_return.or_id'), $request)->paginate($request->limit, [
            'shop_order_return.*', 'shop_order.serial_number as order_number', 'user_mobile', 'pay_price', 'freight',
            'order_contacts', 'order_contacts_mobile', 'order_contacts_address', 'order_note',
        ]));
    }

    /**
     * userPaging
     * @param ProductOrderReturnUserPageRequest $request
     * @return array
     */
    public function userPaging(ProductOrderReturnUserPageRequest $request): array
    {
        request()->offsetSet('buyUserId', USERID);
        $builder = $this->newQuery()
            ->leftJoin('shop_order', 'shop_order.order_id', 'shop_order_return.order_id')
            ->where('or_is_delete', 2)->orderByDesc('or_add_time');
        if (!is_null($request->keyword)) {
            $builder->leftJoin('shop_order_goods', 'shop_order_goods.order_id', 'shop_order_return.order_id')
                ->where(function ($query) use ($request) {
                    $query->where('shop_order_goods.title', 'like', "%{$request->keyword}%")
                        ->orWhere('shop_order_return.serial_number', 'like', "%{$request->keyword}%");
                    $query->orWhere('shop_order.serial_number', 'like', "%{$request->keyword}%");
                });
            $request->offsetUnset('keyword');
        }
        return $this->hPaginate($builder, $request);
    }

    /**
     * sellerPaging
     * @param ProductOrderReturnSellerPageRequest $request
     * @return array
     */
    public function sellerPaging(ProductOrderReturnSellerPageRequest $request): array
    {
        request()->offsetSet('sellUserId', USERID);
        $builder = $this->newQuery()->leftJoin('shop_order', 'shop_order.order_id', 'shop_order_return.order_id')
            ->leftJoin('shop_user', 'shop_user.user_id', 'shop_order_return.buy_user_id')
            ->leftJoin('shop_order_ext', 'shop_order_ext.order_id', 'shop_order.order_id')
            ->where('shop_order_return.or_buy_status', '!=', 0)
            ->whereNull('system_at')->orderByDesc('or_add_time');
        $this->dateFilter($request, $builder, 'orderAddTime');
        if (!is_null($request->keyword)) {
            $builder->leftJoin('shop_order_goods', 'shop_order_goods.order_id', 'shop_order_return.order_id')
                ->where(function ($query) use ($request) {
                    $query->where('shop_order_goods.title', 'like', "%{$request->keyword}%")
                        ->orWhere('shop_user.user_mobile', 'like', "%{$request->keyword}%");
                    if ($request->post('shopOrderExt.status') === 6) {
                        $query->orWhere('shop_order_return.serial_number', 'like', "%{$request->keyword}%");
                    }
                    $query->orWhere('shop_order.serial_number', 'like', "%{$request->keyword}%");
//                    $query->where('shop_order_goods.title', 'like', "%{$request->keyword}%")
//                        ->orWhere('shop_order.serial_number', 'like', "%{$request->keyword}%")
//                        ->orWhere('shop_user.user_mobile', 'like', "%{$request->keyword}%");
                });
            $request->offsetUnset('keyword');
        }
        return $this->hPaginate($builder, $request, [
            'shop_order.serial_number as orderNumber',
            'user_name', 'user_mobile', 'or_api_time',
        ]);
    }

    /**
     * userDetail
     * @param string $serialNumber
     * @return Model|null
     */
    public function userDetail(string $serialNumber): ?Model
    {
        return self::query()->leftJoin('shop_order', 'shop_order.order_id', 'shop_order_return.order_id')->where([
            'shop_order_return.serial_number' => $serialNumber,
            'shop_order_return.buy_user_id' => USERID,
            'or_is_delete' => 2,
        ])->first(array_merge($this->hColumns(), [
            'or_note', 'or_sell_reject_remark',
            'shop_order.serial_number as orderNumber',
            'or_contacts',
            'or_contacts_mobile',
            'or_contacts_address',
            'or_sell_reject_remark',
            'discount',
            'active_discount',
        ]));
    }

    /**
     * sellerDetail
     * @param string $serialNumber
     * @return Model|null
     */
    public function sellerDetail(string $serialNumber): ?Model
    {
        return self::query()->leftJoin('shop_user', 'shop_user.user_id', 'shop_order_return.buy_user_id')
            ->leftJoin('shop_order', 'shop_order.order_id', 'shop_order_return.order_id')->where(humpToLine([
                'shop_order_return.serialNumber' => $serialNumber,
                'shop_order_return.sellUserId' => USERID,
            ]))->first(array_merge($this->hColumns(), [
                'or_note', 'or_contacts',
                'or_contacts_mobile',
                'or_contacts_address',
                'or_sell_reject_remark',
                'user_name',
                'user_mobile',
                'shop_order_return.sell_user_id',
                'or_api_time',
                'order_contacts',
                'order_contacts_mobile',
                'order_contacts_address',
                'shop_order.serial_number as orderNumber',
                'discount',
                'active_discount',
            ]));
    }

    private function hColumns(): array
    {
        return [
            'or_id',
            'shop_order_return.serial_number',
            'shop_order_return.order_id',
            'or_buy_status',
            'or_sell_status',
            'or_sn',
            'or_type',
            'or_reason',
            'or_num',
            'or_price',
            'or_real_price',
            'or_ensure_price',
            'img_id_json',
            'order_goods_ids',
            DB::raw("if(or_approved_time>0,from_unixtime(or_approved_time, '%Y-%m-%d %H:%i:%s'),null) as auditAt"),
            DB::raw("from_unixtime(or_add_time, '%Y-%m-%d %H:%i:%s') as createdAt"),
        ];
    }

    private function hPaginate(Builder $builder, BasePageRequest $request, array $columns = []): array
    {
        $paginate = paginate(helpBuilder($builder, $request)
            ->paginate($request->limit, array_merge($this->hColumns(), $columns)));
        $ids = $oIds = [];
        foreach ($paginate['data'] as $v) {
            if (is_null($v->order_goods_ids)) $oIds[] = $v->order_id;
            else $ids = array_merge($ids, array_keys($v->order_goods_ids));
        }
        if (empty($ids)) $paginate['goods'] = null;
        else $paginate['goods'] = hCollection(ShopOrderGoodsLogic::getByWhere(['whereIn' => ['id', $ids]], null, [
            'id', 'price', 'title', 'spec', 'product_file_id', 'spec_file_id',
        ]));
        if (empty($oIds)) $paginate['good'] = null;
        else $paginate['good'] = hCollection(ShopOrderGoodsLogic::getByWhere(['whereIn' => ['orderId', $oIds]], null, [
            'order_id', 'price', 'title', 'spec', 'product_file_id', 'spec_file_id',
        ]), 'order_id');
        return $paginate;
    }

    public function setImgIdJsonAttribute($value): void
    {
        if (empty($value)) $this->attributes['img_id_json'] = null;
        else $this->attributes['img_id_json'] = json_encode($value);
    }

    public function getImgIdJsonAttribute($value): ?array
    {
        if (empty($value)) return null;
        else return json_decode($value, true);
    }
}
